#ifndef _ERP_GEO_HELPER_H_
#define _ERP_GEO_HELPER_H_

#include <string>
#include <vector>
#include <map>

namespace library
{
namespace geo
{

const static double PI           = 3.14159265f;
const static double EARTH_RADIUS = 6378.137f;


class CGeoCoordinate;
typedef std::vector<CGeoCoordinate> GeoGroup;

class CGeoCoordinate {
public:
	CGeoCoordinate();
	CGeoCoordinate(double dbX, double dbY);

	void SetX(double dbX);
	void SetY(double dbY);
	void SetXY(double dbX, double dbY);

	double GetX() const;
	double GetY() const;

private:
	double m_dbX;  // Longitude
	double m_dbY;  // Latitude
};

class CGeoConfig {
public:
	// distance设置为0,则使用默认配置
	static void SetThreshold4TrustLevel(
			double dbDistanceLevel1 = 500,   // 地图间相似点距离500米
			double dbDistanceLevel2 = 2000,  // 地图间相似点距离2000米
			double dbDistanceLevel3 = 3000,  // 地图最短,第二短距离平均3000米
			double dbDistanceLevel4 = 1000,  // 仅2点满足条件且最短距离1000
			double dbDistanceLevel5 = 2000); // 满足条件最短距离2000米

	static double GetLevel1Threshold();
	static double GetLevel2Threshold();
	static double GetLevel3Threshold();
	static double GetLevel4Threshold();
	static double GetLevel5Threshold();

private:
	static double m_dbDistanceLevel1;
	static double m_dbDistanceLevel2;
	static double m_dbDistanceLevel3;
	static double m_dbDistanceLevel4;
	static double m_dbDistanceLevel5;
};

class CGeoHelper {
public:
	static int SelectClosestCoordinate(
				const std::map<uint32_t, GeoGroup > & mapEarthType2GeoGroup,
				CGeoCoordinate& oClosestCoordinate,
				uint32_t& dwTrustLevel);

	static bool CheckCoordinateInPolyGon(
				const CGeoCoordinate& oCoordinate,
				const GeoGroup& oPolyGonCoordinates);

private:
	static double GetEarthDistance(double dbX1, double dbY1, double dbX2, double dbY2);

	static double GetEarthDistance(
					const CGeoCoordinate& oCoordinate1,
					const CGeoCoordinate& oCoordinate2);

	static int Select3ClosestCoordinate(
					const std::vector<GeoGroup >& vecGeoGroup,
					GeoGroup& oShortestCroup,
					double& dbMaxSideDistance);

	static int Select2ClosestCoordinate(
					const std::vector<GeoGroup >& vecGeoGroup,
					GeoGroup& oShort1stCroup,
					GeoGroup& oShort2ndCroup,
					double& dbShort1stDistance,
					double& dbShort2ndDistance,
					double& dbAverageDistance);

	static void Bd2Gcj(
					const CGeoCoordinate& oBdCustormCoordinate,
					CGeoCoordinate& oBdStandardCoordinate);

};

}
}

#endif /*_ERP_GEO_HELPER_H_*/
